package com.bdc.Util;

import java.sql.*;

public class PhoenixJDBCUtils {
    private static String driverClassName;
    private static String URL;
    private static String username;
    private static String password;
    private static boolean autoCommit;

    /** 声明一个 Connection类型的静态属性，用来缓存一个已经存在的连接对象 */
    private static Connection conn;
    static {
        config();
    }
    /**     * 开头配置自己的数据库信息     */
    private static void config() {
        /*         * 获取驱动         */
        driverClassName = "org.apache.phoenix.jdbc.PhoenixDriver";
        /*         * 获取URL         */
        URL = "jdbc:phoenix:slave1,slave2,slave3:2181/hbase";
        /*         * 获取用户名         */
        username = "";
        /*         * 获取密码         */
        password = "";
        /*         * 设置是否自动提交，一般为false不用改         */
        autoCommit = true;
    }
    /**     * 载入数据库驱动类     */
    private static boolean load() {
        try {
            Class.forName(driverClassName);
            return true;
        } catch (ClassNotFoundException e) {
            System.out.println("驱动类 " + driverClassName + " 加载失败");
        }
        return false;
    }

    /**     * 建立数据库连接     */
    public static Connection connect() {
        /* 加载驱动 */
        load();
        try {
            /* 建立连接 */
            conn = DriverManager.getConnection(URL, username, password);
        } catch (SQLException e) {
            System.out.println("建立数据库连接失败 , " + e.getMessage());
        }
        return conn;
    }

    /**     * 设置是否自动提交事务     **/
    public static void transaction() {
        try {
            conn.setAutoCommit(autoCommit);
        } catch (SQLException e) {
            System.out.println("设置事务的提交方式为 : " + (autoCommit ? "自动提交" : "手动提交") + " 时失败: " + e.getMessage());
        }
    }

    /**     * 创建 Statement 对象     */
    public static Statement statement() {
        Statement st = null;
        connect();
        /* 如果连接是无效的就重新连接 */
        transaction();
        /* 设置事务的提交方式 */
        try {
            st = conn.createStatement();
        } catch (SQLException e) {
            System.out.println("创建 Statement 对象失败: " + e.getMessage());
        }
        return st;
    }

    /**     * 根据给定的带参数占位符的SQL语句，创建 PreparedStatement 对象     *
     * @param SQL    带参数占位符的SQL语句
     * @return 返回相应的 PreparedStatement 对象
     */
    private static PreparedStatement prepare(String SQL, boolean autoGeneratedKeys) {
        PreparedStatement ps = null;
        connect();
        /* 如果连接是无效的就重新连接 */
        transaction();
        /* 设置事务的提交方式 */
        try {
            if (autoGeneratedKeys) {
                ps = conn.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS);
            } else {
                ps = conn.prepareStatement(SQL);
            }
        } catch (SQLException e) {
            System.out.println("创建 PreparedStatement 对象失败: " + e.getMessage());
        }
        return ps;
    }

    public static ResultSet query(String SQL, Object... params) {
        if (SQL == null || !SQL.trim().toLowerCase().startsWith("select")) {
            throw new RuntimeException("你的SQL语句为空或不是查询语句");
        }
        ResultSet rs = null;
        if (params.length > 0) {
            /* 说明 有参数 传入，就需要处理参数 */
            PreparedStatement ps = prepare(SQL, false);
            try {
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i + 1, params[i]);
                }
                rs = ps.executeQuery();
            } catch (SQLException e) {
                System.out.println("执行SQL失败: " + e.getMessage());
            }
        } else {
            /* 说明没有传入任何参数 */
            Statement st = statement();
            try {
                rs = st.executeQuery(SQL); // 直接执行不带参数的 SQL 语句
            } catch (SQLException e) {
                System.out.println("执行SQL失败: " + e.getMessage());
            }
        }
        return rs;
    }

    /**     *  释放资源     *   **/
    public static void release(Object cloaseable) {
        if (cloaseable != null) {
            if (cloaseable instanceof ResultSet) {
                ResultSet rs = (ResultSet) cloaseable;
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (cloaseable instanceof Statement) {
                Statement st = (Statement) cloaseable;
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (cloaseable instanceof Connection) {
                Connection c = (Connection) cloaseable;
                try {
                    c.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
